package com.wudgaby.spring.shiro.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresGuest;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {
    private static final Logger log = LoggerFactory.getLogger(LoginController.class);

    @GetMapping("/login")
    public ModelAndView index() {
    	Subject subject = SecurityUtils.getSubject();
    	return new ModelAndView("login", "name", subject.getPrincipal());
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ModelAndView login(@RequestParam String userName, @RequestParam String password){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
        token.setRememberMe(true);
        ModelAndView mav = new ModelAndView("success");

        if(subject.isRemembered()){
            mav.setViewName("fail");
            mav.addObject("error", "已记住我.我是 :"+subject.getPrincipal());
            return mav;
        }

        if(subject.isAuthenticated()){
            mav.setViewName("fail");
            mav.addObject("error", "已认证");
            return mav;
        }

        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            log.error("登录失败.原由{}",e.getMessage());
            mav.setViewName("fail");
            mav.addObject("error", e.getMessage());
        }
        return mav;
    }

    @RequiresRoles("admin")
    @RequestMapping("/admin")
    public ModelAndView admin(){
        return new ModelAndView("logout", "msg", "admin");
    }

    @RequiresRoles("account")
    @RequestMapping("/account")
    public ModelAndView account(){
        return new ModelAndView("logout", "msg", "account");
    }

    @RequiresGuest
    @RequestMapping("/guest")
    public ModelAndView guest(){
        Subject subject = SecurityUtils.getSubject();
        log.info("[guest] isRemembered:{}, isAuthenticated:{}", subject.isRemembered(), subject.isAuthenticated());
        return new ModelAndView("logout", "msg", "guest");
    }

    @RequiresAuthentication
    @RequestMapping("/auth")
    public ModelAndView auth(){
        Subject subject = SecurityUtils.getSubject();
        log.info("[auth] isRemembered:{}, isAuthenticated:{}", subject.isRemembered(), subject.isAuthenticated());
        return new ModelAndView("logout", "msg", "auth");
    }

    @RequiresUser
    @RequestMapping("/user")
    public ModelAndView user(){
        Subject subject = SecurityUtils.getSubject();
        log.info("[user] isRemembered:{}, isAuthenticated:{}", subject.isRemembered(), subject.isAuthenticated());
        return new ModelAndView("logout", "msg", "user");
    }
}
